﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace KaartenLib
{
    public class KaartSpel:IEnumerable<Kaart>
    {
        private List<Kaart> kaarten;
        private Random random = new Random();

        //Constructors
        public KaartSpel()
        {
            kaarten = new List<Kaart>();
            MaakDeck();
        }

        public KaartSpel(IEnumerator<Kaart> deck)
        {
            kaarten = (List<Kaart>)deck;
        }

        //Methoden
        public int AantalKaarten
        {
            get
            {
                return this.kaarten.Count;
            }
        }

        public void MaakDeck()
        {
            foreach (Types t in Enum.GetValues(typeof(Types)))
            {
                foreach (Waarden w in Enum.GetValues(typeof(Waarden)))
                {
                    kaarten.Add(new Kaart(t, w));
                }
            }
        }

        public void VoegKaartToe(Kaart kaart)
        {
            if (kaart == null)
            {
                throw new CardNotFoundException("Kaart mag niet null zijn.");
            }

            kaarten.Add(kaart);
        }

        public void VoegKaartenToe(IEnumerator<Kaart> kaarten)
        {
            if (kaarten == null)
            {
                throw new CardNotFoundException("Kaartenlijst mag niet null zijn.");
            }

            this.kaarten.AddRange((List<Kaart>)kaarten);
        }

        public Kaart TrekRandomKaart()
        {
            return TrekKaart(random.Next(this.AantalKaarten));
        }

        public Kaart TrekBovensteKaart()
        {
            return TrekKaart(0);
        }

        public Kaart TrekKaart(int index)
        {
            if (index < 0 || index > kaarten.Count)
            {
                throw new DomainException("Index is te groot/te klein.");
            }

            Kaart kaart = kaarten.ElementAt(index);
            kaarten.RemoveAt(index);
            if (!ZoekKaart(kaart.Type) && OnLaatsteTypeKaart != null)
            {
                KaartArgs myArgs = new KaartArgs("Laatste kaart van type : " + kaart.Type + " is getrokken.");
                OnLaatsteTypeKaart(this, myArgs);
            }
            return kaart;
        }

        public Kaart TrekKaart(Types type, Waarden waarde)
        {

            if (!Enum.IsDefined(typeof(Types), type))
            {
                throw new DomainException("Type kon niet gevonden worden.");
            }
            if (!Enum.IsDefined(typeof(Waarden), waarde))
            {
                throw new DomainException("Waarde kon niet gevonden worden.");
            }

            Kaart gevondenKaart = null;
            Boolean gevonden = false;

            for (int i = 0; i< kaarten.Count() && !gevonden; i++)
            {
                if (kaarten[i].Waarde == waarde && kaarten[i].Type == type)
                {
                    gevondenKaart = TrekKaart(i);
                    gevonden = true;
                }
            }

            return gevondenKaart;
        }

        public Boolean ZoekKaart(Types type)
        {
            Boolean gevonden = false;

            for (int i = 0; i < 13 || !gevonden; i++)
            {
                if(kaarten[i].Type == (Types) type) {
                    gevonden = true;
                }
            }
            return gevonden;
        }

        public void SchudKaartSpel()
        {
            var n = kaarten.Count;
            while (n > 1)
            {
                n--;
                var k = random.Next(n + 1);
                var value = kaarten[k];
                kaarten[k] = kaarten[n];
                kaarten[n] = value;
            }
        }

        public IEnumerator<Kaart> GetEnumerator()
        {
            foreach (Kaart kaart in kaarten)
            {
                yield return kaart;
            }
        }

        public delegate void KaartSpelHandler(object myObject, KaartArgs myArgs);

        public event KaartSpelHandler OnLaatsteTypeKaart;

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            throw new NotImplementedException();
        }
    }
}